﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web;

using ERPStore.Web.Html;
using ERPStore.Web.NewsLetters.Html;
using ERPStore.NewsLetters.Services;
using ERPStore.Extensions;

using CloudSoft.Extensions;

namespace ERPStore.Web.NewsLetters.Controllers
{
	[HandleError(View = "500")]
	public class NewsLettersController : ERPStore.Web.Controllers.StoreController
	{
		private readonly byte[] GifData = {
      0x47, 0x49, 0x46, 0x38, 0x39, 0x61,
      0x01, 0x00, 0x01, 0x00, 0x80, 0xff,
      0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
      0x00, 0x2c, 0x00, 0x00, 0x00, 0x00,
      0x01, 0x00, 0x01, 0x00, 0x00, 0x02,
      0x02, 0x44, 0x01, 0x00, 0x3b
  };

		public NewsLettersController(
			ERPStore.NewsLetters.Services.NewsLettersService newsLettersService
			, ERPStore.Services.IAccountService accountService
			, ERPStore.Services.CryptoService cryptoService
			, ERPStore.Services.ICatalogService catalogService
			, ERPStore.NewsLetters.Services.TrackerService trackerService
			, ERPStore.Services.IDocumentService documentService
			, ERPStore.Services.IServiceBus serviceBus
			)
		{
			this.NewsLettersService = newsLettersService;
			this.AccountService = accountService;
			this.CryptoService = cryptoService;
			this.CatalogService = catalogService;
			this.TrackerService = trackerService;
			this.DocumentService = documentService;
			this.ServiceBus = serviceBus;
		}

		protected ERPStore.NewsLetters.Services.NewsLettersService NewsLettersService { get; private set; }
		protected ERPStore.Services.IAccountService AccountService { get; private set; }
		protected ERPStore.Services.CryptoService CryptoService { get; private set; }
		protected ERPStore.Services.ICatalogService CatalogService { get; private set; }
		protected ERPStore.NewsLetters.Services.TrackerService TrackerService { get; set; }
		protected ERPStore.Services.IDocumentService DocumentService { get; set; }
		protected ERPStore.Services.IServiceBus ServiceBus { get; private set; }

		[ERPStore.Web.Controllers.ActionFilters.ZeroCacheActionFilter]
		public ActionResult NewsLetterPreview(string key)
		{
			var trackingKey = new ERPStore.NewsLetters.Models.TrackingKey();
			CryptoService.Decrypt(key, trackingKey);

			var campaign = new ERPStore.NewsLetters.Models.Campaign();
			campaign.NewsLetterId = trackingKey.NewsLetterId;
			campaign.Name = "Preview";

			var newsLetter = NewsLettersService.GetNewsLetterById(trackingKey.NewsLetterId);

			var user = new ERPStore.NewsLetters.Models.EmailRecipient();
			user.Email = trackingKey.Email;
			user.Presentation = ERPStore.Models.UserPresentation.Mister;
			user.Id = -1;
			user.FirstName = "FirstName" ;
			user.LastName = "LastName" ;
			user.FullName = user.FirstName + " " + user.LastName;

			ViewData.Model = new ERPStore.NewsLetters.Models.CustomerNewsLetter()
			{
				Campaign = campaign,
				NewsLetter = newsLetter,
				Recipient = user,
				ShowEmailLink = true,
				ShowUnsubscribeLink = true,
			};

			ViewBag.Recipient = user;

			return View(newsLetter.ContentViewName);
		}

		[ERPStore.Web.Controllers.ActionFilters.TrackerActionFilter]
		[ERPStore.Web.Controllers.ActionFilters.ZeroCacheActionFilter]
		public ActionResult NewsLetter(string key)
		{
			if (key.IsNullOrTrimmedEmpty())
			{
				return RedirectToERPStoreRoute(ERPStore.Web.Routing.ERPStoreRoutes.HOME);
			}

			// Decryptage de la clé
			var trakingKey = new ERPStore.NewsLetters.Models.TrackingKey();
			CryptoService.Decrypt(key, trakingKey);

			var campaign = NewsLettersService.GetCampaignById(trakingKey.CampaignId);
			var newsLetter = NewsLettersService.GetNewsLetterById(trakingKey.NewsLetterId);
			var recipient = NewsLettersService.GetEmailRecipientByEmail(trakingKey.Email);
			if (campaign == null)
			{
				campaign = new ERPStore.NewsLetters.Models.Campaign();
				campaign.Id = -1; // Preview;
				campaign.Name = "Preview";
				campaign.NewsLetterId = newsLetter.Id;
			}

			ViewData.Model = new ERPStore.NewsLetters.Models.CustomerNewsLetter()
				{
					Campaign = campaign,
					NewsLetter = newsLetter,
					Recipient = recipient,
                    ShowEmailLink = false,
                    ShowUnsubscribeLink = true,
				};

			var message = new ERPStore.NewsLetters.Events.NewsLetterTrackEvent()
			{
				Track = trakingKey,
				DestinationUrl = Request.RawUrl,
				Ip = Request.UserHostAddress,
				UserAgent = Request.UserAgent,
				RawUrl = Request.RawUrl,
			};

			ServiceBus.Send(ERPStore.NewsLetters.Queues.QUEUE_TRACK, message);

			return View(newsLetter.ContentViewName);
		}

		[ERPStore.Web.Controllers.ActionFilters.ZeroCacheActionFilter]
		public ActionResult HtmlNewsLetter(ERPStore.NewsLetters.Models.CustomerNewsLetter customerNewsLetter)
		{
			ViewData["ShowUnsubscribeLink"] = true;
			ViewData["ShowEmailLink"] = true;
			ViewData.Model = customerNewsLetter;
			var homePath = HttpContext.Server.MapPath("/");
			var viewName = customerNewsLetter.NewsLetter.ContentViewName.Replace(homePath, "");
			return View(viewName);
		}

		//[ERPStore.Web.Controllers.ActionFilters.TrackerActionFilter]
		//[ERPStore.Web.Controllers.ActionFilters.ZeroCacheActionFilter]
		//public ActionResult Landing(string landingLink, string key)
		//{
		//    var trakingKey = new Models.TrackingKey();
		//    CryptoService.Decrypt(key, trakingKey);

		//    var campaign = this.NewsLettersService.GetCampaignById(trakingKey.CampaignId);
		//    var newsletter = NewsLettersService.GetNewsLetterById(trakingKey.NewsLetterId);
		//    var recipient = NewsLettersService.GetEmailRecipientByEmail(trakingKey.Email);

		//    ViewData.Model = new Models.CustomerNewsLetter()
		//    {
		//        Campaign = campaign,
		//        Recipient = recipient,
		//        NewsLetter = newsletter,
		//    };
		//    return View(newsletter.LandingViewName);
		//}

		[ERPStore.Web.Controllers.ActionFilters.TrackerActionFilter]
		[HttpPost]
		public ActionResult Subscribe(string email)
		{
			if (email == null
				|| !ERPStore.Validators.EmailValidator.IsValidEmail(email))
			{
				ViewBag.Success = false;
				return View();
			}

			var user = User.CurrentUser;

			if (user != null
				&& user.Email != null
				&& user.Email.Equals(email, StringComparison.InvariantCultureIgnoreCase))
			{
				ViewBag.Success = false;
				return View();
			}
			else if (user == null)
			{
				var visitorId = User.VisitorId;
				var registration = AccountService.GetRegistrationUser(visitorId);
				if (registration == null)
				{
					registration = AccountService.CreateRegistrationUser();
				}
				registration.Email = email;
				AccountService.SaveRegistrationUser(visitorId, registration);
			}

			ViewBag.Success = true;
			return View();
		}

		[ERPStore.Web.Controllers.ActionFilters.TrackerActionFilter]
		public ActionResult Unsubscribe(string key)
		{
			// Decryptage de la clé
			var mailKey = new ERPStore.NewsLetters.Models.TrackingKey();
			CryptoService.Decrypt(key, mailKey);

			ViewData["email"] = mailKey.Email;
			NewsLettersService.Unsubscribe(mailKey.Email, mailKey.NewsLetterId);

			var message = new ERPStore.NewsLetters.Events.NewsLetterTrackEvent()
			{
				Track = mailKey,
				DestinationUrl = Request.RawUrl,
				Ip = Request.UserHostAddress,
				UserAgent = Request.UserAgent,
				RawUrl = Request.RawUrl,
			};
			ServiceBus.Send(ERPStore.NewsLetters.Queues.QUEUE_TRACK, message);

			return View();
		}

		public ActionResult Images(string resource)
		{
			var m_VirtualFilePath = ERPStore.NewsLetters.Configuration.ConfigurationSettings.AppSettings["virtualFilePath"];
			var m_PhysicalPath = ERPStore.GlobalConfiguration.Configuration.Settings.PhysicalPath;
			m_PhysicalPath = System.IO.Path.Combine(m_PhysicalPath, m_VirtualFilePath.Replace("~/", "").Replace("/", @"\"));
			m_PhysicalPath = System.IO.Path.Combine(m_PhysicalPath, "img");
			var fullFileName = System.IO.Path.Combine(m_PhysicalPath, resource);

			// Ajout du cache d'image
			Response.Cache.SetCacheability(HttpCacheability.Public);
			Response.Cache.SetExpires(DateTime.Now.AddDays(1));
			Response.Cache.SetLastModified(DateTime.Now);

			string mimeType = "image/png";
			var extension = System.IO.Path.GetExtension(fullFileName);
			if (extension != null)
			{
				extension = extension.Trim('.');
				var mime = ERPStore.Extensions.MimeExtensions.MIMETypeDictionary.FirstOrDefault(i => i.Key.Equals(extension, StringComparison.InvariantCultureIgnoreCase));
				if (mime.Value != null)
				{
					mimeType = mime.Value;
				}
			}

			return this.File(fullFileName, mimeType);
		}

		[ERPStore.Web.Controllers.ActionFilters.ZeroCacheActionFilter]
        public ActionResult NLRedirect(string route, string key)
        {
            if (route.IsNullOrEmpty())
            {
                return RedirectToERPStoreRoute(ERPStore.Web.Routing.ERPStoreRoutes.HOME);
            }
			var trakingKey = new ERPStore.NewsLetters.Models.TrackingKey();
            CryptoService.Decrypt(key, trakingKey);

            var urlHelper = new UrlHelper(ControllerContext.RequestContext);
            var url = string.Empty;
            string code = null;
            switch (route.ToLower())
            {
                case "product" :
				case "pd" :
                    code = Request["code"] ?? (string)HttpContext.Items["code"];
					if (code.Equals("P147101"))
					{
						code = "P132208";
					}
                    var product = CatalogService.GetProductByCode(code);
			        if (product == null)
			        {
				        return RedirectToERPStoreRoute(ERPStore.Web.Routing.ERPStoreRoutes.HOME);
			        }
			        url = urlHelper.Href(product);
					// Logger.Notification(url);
                    break;
                case "productcategory" :

					code = Request["code"] ?? (string)HttpContext.Items["code"];
                    var category = CatalogService.GetCategoryByCode(code);
			        if (category == null)
			        {
				        return RedirectToERPStoreRoute(ERPStore.Web.Routing.ERPStoreRoutes.HOME);
			        }
			        url = urlHelper.Href(category);

                    break;
                case "brand" :
					code = Request["code"] ?? (string)HttpContext.Items["code"];
                    var brand = CatalogService.GetBrandByName(code);
			        if (brand == null)
			        {
				        return RedirectToERPStoreRoute(ERPStore.Web.Routing.ERPStoreRoutes.HOME);
			        }
			        url = urlHelper.Href(brand);

                    break;
                default:
                    return new EmptyResult();
            }

            // Demarrer un nouveau track
            url = url.AddParameter("estid", string.Format("nlcp{0}", trakingKey.CampaignId));
			if (trakingKey.CampaignId != 0)
			{
				var campaign = NewsLettersService.GetCampaignById(trakingKey.CampaignId);
				if (campaign != null
					&& campaign.AdditionalUrlParameters.IsNotNullOrEmpty())
				{
					url = url + "&" + campaign.AdditionalUrlParameters.TrimStart('&');
				}
			}

            // TrackerService.ProcessTracking(trakingKey, Request.RawUrl, Request.UserHostAddress, url);

			var message = new ERPStore.NewsLetters.Events.NewsLetterTrackEvent()
			{
				Track = trakingKey,
				DestinationUrl = url,
				Ip = Request.UserHostAddress,
				UserAgent = Request.UserAgent,
				RawUrl = Request.RawUrl,
			};

			ServiceBus.Send(ERPStore.NewsLetters.Queues.QUEUE_TRACK, message);

            if (url.IsNullOrEmpty())
            {
                return RedirectToERPStoreRoute(ERPStore.Web.Routing.ERPStoreRoutes.HOME);
            }

            var sb = new System.Text.StringBuilder();
            sb.Append("<html>");
            sb.Append("<head>");
            sb.AppendFormat("<meta http-equiv=\"refresh\" content=\"0;URL={0}\" />", url);
            sb.Append("</head>");
            sb.Append("<body>");
            sb.Append("</body>");
            sb.Append("</html>");
            return Content(sb.ToString(), "text/html");
        }

		[ERPStore.Web.Controllers.ActionFilters.TrackerActionFilter]
		[ERPStore.Web.Controllers.ActionFilters.ZeroCacheActionFilter]
		public ActionResult Product(string productCode, string key)
		{
            HttpContext.Items.Add("code", productCode);
            return NLRedirect("product", key);
		}

		[ERPStore.Web.Controllers.ActionFilters.TrackerActionFilter]
		[ERPStore.Web.Controllers.ActionFilters.ZeroCacheActionFilter]
		public ActionResult ProductCategory(string productCategoryCode, string key)
		{
			TempData.Add("code", productCategoryCode);
            return NLRedirect("productcategory", key);
		}

		[ERPStore.Web.Controllers.ActionFilters.TrackerActionFilter]
		[ERPStore.Web.Controllers.ActionFilters.ZeroCacheActionFilter]
		public ActionResult Brand(string brandName, string key)
		{
			TempData.Add("code", brandName);
            return NLRedirect("brand", key);
		}
		
		public ActionResult Tag(string key)
		{
			if (key == null)
			{
				return new EmptyResult();
			}

			key = key.Replace("/tag.gif", "");

			bool isBadTag = false;
			var trakingKey = new ERPStore.NewsLetters.Models.TrackingKey();
			try
			{
				CryptoService.Decrypt(key, trakingKey);
			}
			catch
			{
				var v1 = new ERPStore.NewsLetters.Models.TrackingKeyV1();
				try
				{
					CryptoService.Decrypt(key, v1);
					trakingKey.CampaignId = v1.CampaignId;
					trakingKey.CreationDate = v1.CreationDate;
					trakingKey.Email = v1.Email;
					trakingKey.EmailRecipientId = 0;
					trakingKey.LinkName = v1.LinkName;
					trakingKey.NewsLetterId = v1.NewsLetterId;
					trakingKey.UserId = v1.UserId;
				}
				catch
				{
					Logger.Warn("Bad NewsLetter Tag detected : {0}", key);
					isBadTag = true;	
				}
			}

			if (isBadTag)
			{
				return new EmptyResult();
			}

			// TrackerService.ProcessTracking(trakingKey, "openmail", Request.UserHostAddress, "openmail");

			var message = new ERPStore.NewsLetters.Events.NewsLetterTrackEvent()
			{
				Track = trakingKey,
				DestinationUrl = "openmail",
				Ip = Request.UserHostAddress,
				UserAgent = Request.UserAgent,
				RawUrl = "openmail",
			};

			ServiceBus.Send(ERPStore.NewsLetters.Queues.QUEUE_TRACK, message);

			Response.AddHeader(
				"Cache-Control",
				"private, no-cache, no-cache=Set-Cookie, proxy-revalidate");
			Response.AddHeader("Pragma", "no-cache");
			Response.AddHeader("Expires", "Wed, 17 Sep 1975 21:32:10 GMT");
			Response.Buffer = false;
            var ms = new System.IO.MemoryStream(GifData);
            return new FileStreamResult(ms, "image/gif");
		}

		[ERPStore.Web.Controllers.ActionFilters.TrackerActionFilter]
        [ValidateInput(false)]
		[ERPStore.Web.Controllers.ActionFilters.ZeroCacheActionFilter]
		public ActionResult Goto(string landing, string key)
		{
			var trakingKey = new ERPStore.NewsLetters.Models.TrackingKey();
			CryptoService.Decrypt(key, trakingKey);

			var urlHelper = new UrlHelper(ControllerContext.RequestContext);
			if (landing.IsNullOrEmpty())
			{
				return RedirectToERPStoreRoute(ERPStore.Web.Routing.ERPStoreRoutes.HOME);
			}
            var decoded = System.Convert.FromBase64String(landing);
            var str = System.Text.Encoding.UTF8.GetString(decoded);
            str = str.AddParameter("estid", string.Format("nlcp{0}", trakingKey.CampaignId));
			if (trakingKey.CampaignId != 0)
			{
				var campaign = NewsLettersService.GetCampaignById(trakingKey.CampaignId);
				if (campaign != null
					&& campaign.AdditionalUrlParameters.IsNotNullOrEmpty())
				{
					str = str + "&" + campaign.AdditionalUrlParameters.TrimStart('&');
				}
			}

			var message = new ERPStore.NewsLetters.Events.NewsLetterTrackEvent()
			{
				Track = trakingKey,
				DestinationUrl = str,
				Ip = Request.UserHostAddress,
				UserAgent = Request.UserAgent,
				RawUrl = str,
			};
			ServiceBus.Send(ERPStore.NewsLetters.Queues.QUEUE_TRACK, message);


            if (!str.StartsWith("http")
                && !str.StartsWith("/"))
            {
                str = "/" + str;
            }

            return RedirectPermanent(str);
		}

		//private void Publish()
		//{

		//    publisher.Publish(new ERPStore.NewsLetters.Events.SignalNewsLetterTrackEvent()
		//    {
		//        Track = trackingKey,
		//        DestinationUrl = destinationUrl,
		//        Ip = ip,
		//        // UserAgent = Request.UserAgent,
		//        RawUrl = rawUrl,
		//        CreationDate = creationDate,
		//        EmailSentId = emailSentId,
		//    });
		//}

	}
}
